Project Description¶
As electric vehicles become more common, understanding the growth and usage of charging infrastructure is essential for effective planning and development. This project examines electric vehicle charging trends in the United States from 2014 to 2022.
The US Government's Alternative Fuels Data Center maintains records of electric vehicle (EV) charging infrastructure, including charging ports, station locations, and vehicle sales. With the EV market evolving rapidly, analyzing trends in charging facilities and sales is important to inform strategic decisions.
As data scientists, we will explore this data by wrangling and visualizing aggregated yearly records. The data, collected each December, provides a snapshot of EV charging port installations and station locations over roughly ten years, covering both public and private charging environments.
The Data¶
private_ev_charging.csv¶
Variable | Description |
---|---|
year | Year of data collection |
private_ports | Number of charging ports owned by private companies in that year |
private_station_locations | Number of privately owned station locations for EV charging |
public_ev_charging.csv¶
Variable | Description |
---|---|
year | Year of data collection |
public_ports | Number of charging ports under public ownership in that year |
public_station_locations | Number of publicly owned station locations for EV charging |
ev_sales.csv¶
Variable | Description |
---|---|
Vehicle | Electric vehicle model |
year | Year of data collection |
sales | Number of vehicles sold in the US |
# Import required libraries
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Load the datasets
private_ev_charging = pd.read_csv("private_ev_charging.csv")
public_ev_charging = pd.read_csv("public_ev_charging.csv")
ev_sales = pd.read_csv("ev_sales.csv")
private_ev_charging.head()
year | private_ports | private_station_locations | |
---|---|---|---|
0 | 2014 | 3695 | 1825 |
1 | 2015 | 4150 | 1962 |
2 | 2016 | 5763 | 2331 |
3 | 2017 | 6048 | 2370 |
4 | 2018 | 6812 | 2489 |
public_ev_charging.head()
year | public_ports | public_station_locations | |
---|---|---|---|
0 | 2013 | 16619 | 6938 |
1 | 2014 | 22470 | 9207 |
2 | 2015 | 26532 | 10710 |
3 | 2016 | 33165 | 13150 |
4 | 2017 | 45789 | 16170 |
ev_sales.head()
Vehicle | year | sales | |
---|---|---|---|
0 | Chevy Volt | 2011 | 7671.0 |
1 | Chevy Volt | 2012 | 23461.0 |
2 | Chevy Volt | 2013 | 23094.0 |
3 | Chevy Volt | 2014 | 18805.0 |
4 | Chevy Volt | 2015 | 15393.0 |
# Perform an outer join to keep only the rows with complete information
df_combined = private_ev_charging.merge(public_ev_charging, on='year', how='outer', indicator=True)
df_temp = df_combined[df_combined['_merge'] == 'both']
# Drop the _merge column as it's no longer needed
df_temp = df_temp.drop(columns=['_merge'])
df_temp.head()
year | private_ports | private_station_locations | public_ports | public_station_locations | |
---|---|---|---|---|---|
0 | 2014 | 3695.0 | 1825.0 | 22470 | 9207 |
1 | 2015 | 4150.0 | 1962.0 | 26532 | 10710 |
2 | 2016 | 5763.0 | 2331.0 | 33165 | 13150 |
3 | 2017 | 6048.0 | 2370.0 | 45789 | 16170 |
4 | 2018 | 6812.0 | 2489.0 | 56842 | 19893 |
How many vehicles were sold in 2018 in total?¶
# Get total sales grouping by each year
ev_total_sales = ev_sales.groupby('year')['sales'].sum().reset_index()
ev_total_sales[ev_total_sales['year'] == 2018]
year | sales | |
---|---|---|
7 | 2018 | 361315.0 |
Plot trends for private ports, public ports, and sales.¶
# Left-join with sales
df_complete = df_temp.merge(ev_total_sales, how='left', on='year')
# Drop any rows with null values
df_complete = df_complete.dropna(subset="sales")
# Create a figure and axis object
fig, ax = plt.subplots()
# Plot each line
sns.lineplot(data=df_complete, x='year', y='private_ports', label='Private Ports')
sns.lineplot(data=df_complete, x='year', y='public_ports', label='Public Ports')
sns.lineplot(data=df_complete, x='year', y='sales', label='Total Sales', linestyle=':')
# Adding titles and labels
ax.set_title('EV Ports and Sales Over Time')
ax.set(xlabel='Year', ylabel='Count')
# Show the legend
ax.legend(loc='upper left')
plt.show()
C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True): C:\Users\newbe\anaconda3\Lib\site-packages\seaborn\_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead. with pd.option_context('mode.use_inf_as_na', True):
Did vehicle sales and number of private and public ports show the same trend (either increasing or decreasing) between the years 2015 and 2018?¶
# From the above plot we can conclude that vehicle sales and number of private and public ports show the same trend between 2015 and 2018. i.e. increasing